import { resolve } from 'path';
import { arrayBuffer } from 'stream/consumers';

(function () {
	//Class 中的泛型消费方则是属性、方法、乃至装饰器等。同时 Class 内的方法还可以再声明自己独有的泛型参数。

	class Queue<TElementType> {
		private _list: TElementType[];

		constructor(initial: TElementType[]) {
			this._list = initial;
		}

		// 入队一个队列泛型子类型的元素
		enqueue<TType extends TElementType>(ele: TType): TElementType[] {
			this._list.push(ele);
			return this._list;
		}

		// 入队一个任意类型元素（无需为队列泛型子类型）
		enqueueWithUnkownType<TType>(element: TType): (TElementType | TType)[] {
			return [...this._list, element];
		}

		// 出队
		dequeue(): TElementType[] {
			this._list.shift();
			return this._list;
		}

		get list(): TElementType[] {
			return this._list;
		}
	}

	let obj0 = new Queue([true]);
	obj0.enqueue(false);
	obj0.dequeue();
	console.log(obj0.enqueueWithUnkownType(''));
	console.log('obj0.list__', obj0.list);

	// #内置方法中的泛型
	//TypeScript 中为非常多的内置对象都预留了泛型坑位，如 Promise 中
	function p() {
		return new Promise<boolean>((res, rej) => {
			res(true);
		});
	}

	//而在 TypeScript 内部的 Promise 类型声明中同样是通过泛型实现：
	interface PromiseConstructor {
		resolve<T>(value: T | PromiseLike<T>): Promise<T>;
	}
	const arr: Array<number> = [1, 2, 3];
	const arr2: (number | boolean)[] = [1, 2, true];

	// 类型“string”的参数不能赋给类型“number”的参数。
	// arr.push('lys');
	// arr.includes('lys');

	arr.find(() => false);
	// declare var Promise: PromiseConstructor;

	// 第一种 reduce
	arr.reduce((prev, cur, idx, arr) => {
		return prev;
	}, 1);

	// 第二种 reduce
	// 报错：不能将 number 类型的值赋值给 never 类型
	// arr.reduce((prev, curr, idx, arr) => {
	// 	return [...prev, curr];
	// }, []);

	arr.reduce((prev, curr, idx, arr) => {
		return [...prev, curr];
	}, [] as number[]);
})();
